package cn.iocoder.yudao.module.trade.service.order;

import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderUpdateCheckDTO;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.*;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;

import java.math.BigDecimal;
import java.util.List;

/**
 * 交易订单【写】Service 接口
 *
 * @author LeeYan9
 * @since 2022-08-26
 */
public interface TradeOrderUpdateService {

    // =================== Order ===================

    /**
     * 获得订单结算信息
     *
     * @param userId          登录用户
     * @param settlementReqVO 订单结算请求
     * @return 订单结算结果
     */
    AppTradeOrderOrderRespVO orderSettle(Long userId, AppTradeOrderOrderReqVO settlementReqVO);

    /**
     * 【会员】创建交易订单
     *
     * @param userId      登录用户
     * @param createReqVO 创建交易订单请求模型
     * @return 交易订单的
     */
    TradeOrderDO createOrder(Long userId, AppTradeOrderOrderCreateReqVO createReqVO);


    void updateOrderPaid(PayOrderNotifyReqDTO notifyReqDTO);

    void updateOrderPartPaid(String orderNo, Long payOrderId);

    /**
     * 同步订单的支付状态
     *
     * 1. Quietly 表示，即使同步失败，也不会抛出异常
     * 2. 什么时候回出现异常？因为是主动同步，可能和支付模块的回调通知 {@link #updateOrderPaid(PayOrderNotifyReqDTO notifyReqDTO)} 存在并发冲突，导致抛出异常
     *
     * @param id 订单编号
     * @param payOrderId 支付订单编号
     */
    void syncOrderPayStatusQuietly(Long id, Long payOrderId);

    /** 
     * 备货完成
     *
     * @param orderNo 订单编号
     */
    void prepareDone(String orderNo);

    /**
     * 【管理员】发货交易订单
     *
     * @param deliveryReqVO 发货请求
     */
    void deliveryOrder(TradeOrderDeliveryReqVO deliveryReqVO);

    /**
     * 【会员】收货交易订单
     *
     * @param userId 用户编号
     * @param orderNo     订单编号
     */
    void receiveOrderByMember(Long userId, String orderNo);

    void receiveOrderByAdmin(String orderNo);

    /**
     * 【系统】自动收货交易订单
     *
     * @return 收货数量
     */
    int receiveOrderBySystem();

    /**
     * 【会员】取消交易订单
     *
     * @param userId 用户编号
     * @param id     订单编号
     */
    void cancelOrderByMember(Long userId, Long id);

    /**
     * 【系统】自动取消订单
     *
     * @return 取消数量
     */
    int cancelUnpaidOrderBySystem();
    int rollbackPartPaidOrderBySystem();

    /**
     * 【会员】删除订单
     *
     * @param userId 用户编号
     * @param no     订单编号
     */
    void deleteOrder(Long userId, String no);

    /**
     * 【管理员】交易订单备注
     *
     * @param reqVO 请求
     */
    void updateOrderRemark(TradeOrderRemarkReqVO reqVO);

    /**
     * 【管理员】调整价格
     *
     * @param reqVO 请求
     */
    void updateOrderPrice(TradeOrderUpdatePriceReqVO reqVO);

    /**
     * 【管理员】调整地址
     *
     * @param reqVO 请求
     */
    void updateOrderAddress(TradeOrderUpdateAddressReqVO reqVO);

    /**
     * 【管理员】核销订单
     *
     * @param userId 管理员编号
     * @param pickUpVerifyCode 自提核销码
     */
    void pickUpOrderByAdmin(Long userId, String pickUpVerifyCode);

    /**
     * 取消支付订单
     *
     * @param userId           用户编号
     * @param orderId          订单编号
     * @param cancelType       取消类型
     */
    void cancelPaidOrder(Long userId, String orderId, Integer cancelType);

    AppTradeOrderCreateRespVO createPaySettled(String orderNo, BigDecimal orderWeight, Boolean autoPay, Boolean isViolate,
                                               Boolean isStore, List<String> payPicUrl, Long collectInfoId, Long bankInfoId);

    /**
     * 核验后更新订单
     */
    void updateOrderByCheck(TradeOrderUpdateCheckDTO updateCheck);

    AppTradeOrderDetailRespVO confirmCheck(TradeOrderSettleReqVO settleReqVO);

    Boolean settleOrder(TradeOrderSettleReqVO settleReqVO);

    PayOrderCreateReqDTO getSettleInfo(String orderNo, BigDecimal orderWeight, Boolean isViolate);

    AppTradeOrderCreateRespVO createPayOrder(String orderNo, BigDecimal price, Integer payType);

    Boolean updateOrderByCreatePayCheck(Long payOrderId);


    Boolean updateOrderByCollectRejected(Long id);


}
